from flask import Blueprint, jsonify, send_file, request, redirect
from flask_restful import Api, Resource,reqparse
from utils.smscode import sms_code
from utils.myredis import r
from models.user.user import *
from captcha.image import ImageCaptcha

from utils.myjwt import mjwt

login_bp = Blueprint('login_bp', __name__, url_prefix='/')
api = Api(login_bp)

import random
import time
import requests
# 图片验证码
class ImgView(Resource):
    def get(self):
        #  获取前端数据
        req = reqparse.RequestParser()
        req.add_argument('uuid')
        args = req.parse_args()
        # 实例化captcha
        img = ImageCaptcha()
        #  生成一个4位数的验证码
        code = random.randint(1000,9999)
        # 需要转换成 字符串类型
        code1 = str(code)
        #  调用里面的方法  直接返回图片验证码
        img_png = img.generate(code1)
        # 存入redis里
        r.str_add(args['uuid'],code1,3600)
        # 使用flask中的方法返回
        return send_file(img_png,mimetype="png")

api.add_resource(ImgView,'/img')


# 发送手机验证码
class SendSmsCode(Resource):
    def post(self):
        req = reqparse.RequestParser()
        req.add_argument('uuid')
        req.add_argument('mobile')
        req.add_argument('piccode')
        args = req.parse_args()

        # 从redis中取出来 图片验证码
        value = r.str_get(args['uuid'])
        if value:
            if args['piccode'] == value.decode():
                print(value.decode(),222222)
                # 验证一分钟内只能发一次
                mcode = r.str_get(args['mobile'])
                if mcode:
                    return jsonify({'code':10012,'msg':'一分钟内不能重复发'})
                # 调用短信平台
                # 生成5位随机数
                smscode = str(random.randint(1000, 9999))
                flag = sms_code(args['mobile'], smscode)
                if flag:
                    # 手机验证码存入redis
                    r.str_add(args['mobile'],smscode,60)
                    # 删除图片验证码
                    r.del_str(args['uuid'])
                    # 返回结果
                    return jsonify({'code':200,'msg':'发送成功'})
                else:
                    return jsonify({'code': 10013, 'msg': '发送验证码失败'})
            else:
                return jsonify({'code':10011,'msg':'图片验证码错误'})
        else:
            return jsonify({'code': 10010, 'msg': '图片验证码不存在'})

api.add_resource(SendSmsCode,'/sendSmsCode')


# 登录接口
class LoginView(Resource):
    def post(self):
        req = reqparse.RequestParser()
        req.add_argument('smscode')
        req.add_argument('mobile')
        args = req.parse_args()
        # 判断数据是否存在
        if not all([args['smscode'],args['mobile']]):
            return jsonify({
                'code':400,
                'msg':'数据不完整'
            })
        # 从redis中取出  验证码
        code = r.str_get(args['mobile'])
        if code:
            print(code,55555)
            # 判断验证码是否相同
            if int(code.decode()) == int(args['smscode']):
                user = User.query.filter(User.mobile == args['mobile']).first()
                print(user,111111)
                # 如果相同 删除验证码（为了节约内存）
                # 否则  存入到用户表中
                if user:
                    r.del_str(args['mobile'])
                else:
                    u = User(mobile=args['mobile'],nikename=args['mobile'])
                    db.session.add(u)
                    db.session.commit()
                    user = User.query.filter(User.mobile == args['mobile']).first()
                # 返回token给前端  用户id也返回过去
                token = mjwt.jwt_encode({'user_id':user.id,'exp':int(time.time())})
                return jsonify({
                    'code':200,
                    'msg':'登录成功',
                    'token':token,
                    'user_id':user.id
                })
            else:
                return jsonify({'code':400,'msg':'验证码错误'})
        else:
            return jsonify({'code':400,'msg':'验证码已过期'})

api.add_resource(LoginView,'/login')


# 获取weibo地址
class WeiBoUser(Resource):
    def get(self):
        client_id = '3674019597'
        redirect_uri = "http://127.0.0.1:8000/user/weiboCallback/"
        url = "https://api.weibo.com/oauth2/authorize?client_id=%s&redirect_uri=%s&response_type=code" % (
            client_id, redirect_uri)
        return jsonify({'code': 200, 'url': url})

api.add_resource(WeiBoUser,'/getwburl')

import json
class WeiboCallback(Resource):
    def get(self):
        code = request.args.get('code')
        data = {"client_id": '3674019597', "client_secret": "7ae99bc0d54ead29fc8d1b9fabd78587",
                "grant_type": "authorization_code",
                'redirect_uri': 'http://127.0.0.1:8000/user/weiboCallback/', 'code': code}
        res = requests.post('https://api.weibo.com/oauth2/access_token', data=data)
        mes = json.loads(res.text)
        uid = mes["uid"]
        token = mes["access_token"]
        # 查询三方登录表中uid是否存在 如果存在，查询用户表  用用户信息生成token跳转到vue页面
        sql = "select user.id from user inner join sf_login on user.id=sf_login.userid where sf_login.uid='%s'" % (uid)
        user = db.session.execute(sql)
        if user:
            for i in user:
                data = {'data':{'userid':i[0],'exp':int(time.time())}}
                token = mjwt.jwt_encode(data)
                return redirect('http://localhost:8080/#/updateToken?userid='+str(i[0])+'&token='+token)
        # 不存在跳转到vue绑定页面 token uid传递过去
        return redirect('http://localhost:8080/#/bindMobile?uid='+uid+'&token='+token)

api.add_resource(WeiboCallback,'/user/weiboCallback/')

# 绑定手机号
class BindMobile(Resource):
    def post(self):
        data = json.loads(request.data)
        mobile = data['mobile']
        uid = data['uid']
        token = data['token']

        # 先查询用户表  如果手机号存在获取userid  写入三方登录表 生成token
        user = User.query.filter(User.mobile == mobile).first()
        if not user:
            # 添加用户操作
            u = User(mobile=mobile,nikename=mobile)
            db.session.add(u)
            db.session.commit()
            user = User.query.filter(User.mobile == mobile).first()
        # 如果不存在 写入user表
        sfuser = SfLogin(userid=user.id, webfrom='wb', uid=uid, token=token)
        db.session.add(sfuser)
        db.session.commit()

        data = {'data': user.id, 'exp': int(time.time())}
        token = mjwt.jwt_encode(data)
        return jsonify({'userid':str(user.id),'token':token})

api.add_resource(BindMobile,'/bindMobile')


from utils.comm import get_ali_object
# 调用支付宝
class Vipbuy(Resource):
    def post(self):
        req = reqparse.RequestParser()
        req.add_argument('year')
        req.add_argument('userid')
        args = req.parse_args()
        money = 200
        tmoney = money * int(args['year'])
        order_no = str(int(time.time())) + str(args['userid']) + str(random.randint(100,999))
        vip = VipRecord(order_no=order_no,userid=args['userid'],year=args['year'],money=tmoney,active_money=tmoney,status=1)
        db.session.add(vip)
        db.session.commit()
        # 支付页面 支付
        pay = get_ali_object()
        query_params = pay.direct_pay(
            subject='test' + "充值服务",  # 商品简单描述
            out_trade_no=str(order_no),  # 用户购买的商品订单号（每次不一样） 20180301073422891
            total_amount=tmoney,  # 交易金额(单位: 元 保留俩位小数)
        )
        pay_url = "https://openapi.alipaydev.com/gateway.do?{0}".format(query_params)  # 支付宝网关地址（沙箱应用）
        return jsonify({
            'code': 200,
            'url': pay_url
        })

api.add_resource(Vipbuy,'/buy')

#  支付宝回调接口
class Callback(Resource):
    def get(self):
        data = request.args
        datames = {k:v for k,v in data.items()}
        # 删除字典中的额key为sign的记录
        sign = datames.pop('sign')
        # 鉴权 订单号  流水号
        pay = get_ali_object()
        flag = pay.verify(datames,sign)

        if flag == Tags:
            # 支付宝流水号
            transaction_no = datames['trade_no']
            # 订单号
            order_no = datames['out_trade_no']
            # 处理事务
            try:
                # 订单号更新订单表
                record= VipRecord.query.filter(VipRecord.order_no == order_no).first()

                record.status = 2
                record.transaction_no = transaction_no
                db.session.add(record)
                # 更新用户表
                User.query.filter(User.id == record.userid).update({'level':2})
                vip = Vip.query.filter(Vip.userid == record.userid,Vip.status==1).first()
                if vip is not None:
                    # 结束时间 + 购买年限
                    etime = vip.e_time.split("-")
                    tyear = int(etime[0]) + int(record.year)
                    yearstr = "-"
                    etime[0] = str(tyear)
                    retime = yearstr.join(etime)
                    vip.e_time = retime
                    db.session.add(vip)
                else:
                    nowyear = datetime.date.strftime(datetime.datetime.now(),'%Y-%m-%d %H:%m:%s')
                    etime = nowyear.split("-")
                    tyear = int(etime[0]) + int(record.year)
                    etime[0] = str(tyear)
                    yearstr = "-"
                    retime = yearstr.join(etime)

                    vip = Vip(userid=record.userid,s_time=datetime.datetime.now(),e_time=retime)
                    db.session.add(vip)
                db.session.commit()
            except:
                db.session.rollback()
        else:
            print('鉴权失败')
        return redirect('http://localhost:8080/#/vip')

api.add_resource(Callback,'/callback')


# 获取 类别 标签数据
class getTags(Resource):
    def get(self):
        t = Tags.query.all()
        type_list = [{'id':i.id,'name':i.name} for i in t]
        ct = Ctype.query.all()
        ctype = [{'id': i.id, 'name': i.name} for i in ct]
        return jsonify({'code':200,'msg':'类别获取成功','tags':type_list,'ctype':ctype})

api.add_resource(getTags,'/tags')

# 获取标签下的数据
from db import db
class Getcoures(Resource):
    def get(self):
        req = reqparse.RequestParser()
        req.add_argument('id')
        args = req.parse_args()

        if not args['id']:
            return jsonify({'code':400,'msg':'数据不存在'})
        sql = "select * from course as c inner join course_tag as ct on ct.courseid=c.id where ct.tagid=" + args['id']
        res = db.find_all(sql)

        return jsonify({'code':200,'msg':'ok','course':res})

api.add_resource(Getcoures,'/getcou')

# 类别全部的数据
class Getctype(Resource):
    def get(self):
        sql = "select * from course "
        res = db.find_all(sql)
        return jsonify({'code':200,'msg':'ok','ctypr':res})
api.add_resource(Getctype,'/getctype')


# 获取 免费 或 会员 数据
class Getis_vip(Resource):
    def get(self):
        req = reqparse.RequestParser()
        req.add_argument('id')
        args = req.parse_args()

        if not args['id']:
            return jsonify({'code':400,'msg':'数据不存在'})
        # 免费
        if int(args['id']) == 2:
            sql = "select * from course where is_vip=0"
            res = db.find_all(sql)
            return jsonify({'code':200,'getvip':res})
        # 会员
        if int(args['id']) == 3:
            tsql = "select * from course where is_vip=1"
            tres = db.find_all(tsql)
            return jsonify({'code': 200, 'getvip': tres})
        # 全部
        else:
            qsql = "select * from course"
            qres = db.find_all(qsql)
            return jsonify({'code': 200, 'getvip': qres})

api.add_resource(Getis_vip,'/getvip')

# 已上线  即将上线
class GetIs_publish(Resource):
    def get(self):
        req = reqparse.RequestParser()
        req.add_argument('id')
        args = req.parse_args()
        print(args['id'])

        if not args['id']:
            return jsonify({'code':400,'msg':'数据不存在'})
        sql = "select * from course where is_publish = '%d'"%int(args['id'])
        res = db.find_all(sql)
        print(res)
        return jsonify({'code':200,'pub':res})
api.add_resource(GetIs_publish,'/getpub')

# 最新 最热 数据
class Get_hew_hot(Resource):
    def get(self):
        type = request.args.get("type")
        if not type:
            return jsonify({'code': 400, 'msg': '数据不存在'})
        if int(type) == 1:
            sql = "select * from course order by create_time desc"
            res = db.find_all(sql)
            return jsonify({"code": 200, 'data': res})
        if int(type) == 2:
            sql1 = 'select * from course order by views desc'
            ress = db.find_all(sql1)
            return jsonify({"code": 200, 'data': ress})

api.add_resource(Get_hew_hot,'/hew_hot')

# 详情
class Getcourse_info(Resource):
    def get(self):
        req = reqparse.RequestParser()
        req.add_argument('id')
        args = req.parse_args()

        if not args['id']:
            return jsonify({'code':400,'msg':'数据不存在'})

        sql = "select * from jie where jie.courseid ='%d'"%int(args['id'])
        res = db.find_all(sql)

        return jsonify({'code':200,'msg':'ok','data':res})

api.add_resource(Getcourse_info,'/xq')


class GetVideo(Resource):
    def get(self):
        req =reqparse.RequestParser()
        req.add_argument('id')
        args = req.parse_args()

        if not args['id']:
            return jsonify({'code':400,'msg':'数据不存在'})

        sql = "select * from jie where jie.id = '%d'"%int(args['id'])
        res = db.findone(sql)
        return jsonify({'code':200,'msg':'ok','data':res})
api.add_resource(GetVideo,'/getvideo')
